﻿using Core.FrameWork.Commons.DependencyInjection;
using Core.FrameWork.Commons.Hepler;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;

namespace Core.Web.Api.Utils.Init
{
    public static class InitAutoScanInjection
    {
        /// <summary>
        /// 添加自动扫描注入Service服务和Respository仓储
        /// 
        /// <para>
        /// 需要注意的是，遵循如下约定：
        /// IUserService --> UserService, IUserRepository --> UserRepository.
        /// </para>
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddAutoScanInjection(this IServiceCollection services)
        {

            foreach (var item in RuntimeHelper.GetAllCoreAssemblies())
            {
                foreach (var install in item.GetTypes().Where(t => typeof(IPrivateDependency).IsAssignableFrom(t) && t.IsClass))
                {
                    var serviceType = install.GetInterface($"I{install.Name}");
                    if ((serviceType ?? install).GetInterface(typeof(ISingletonDependency).Name) != null)
                    {
                        if (serviceType != null)
                        {
                            services.AddSingleton(serviceType, install);
                        }
                        else
                        {
                            services.AddSingleton(install);
                        }
                    }
                    else if ((serviceType ?? install).GetInterface(typeof(IScopedDependency).Name) != null)
                    {
                        if (serviceType != null)
                        {
                            services.AddScoped(serviceType, install);
                        }
                        else
                        {
                            services.AddScoped(install);
                        }
                    }
                    else if ((serviceType ?? install).GetInterface(typeof(ITransientDependency).Name) != null)
                    {
                        if (serviceType != null)
                        {
                            services.AddTransient(serviceType, install);
                        }
                        else
                        {
                            services.AddTransient(install);
                        }
                    }
                    else
                    {
                        if (serviceType != null)
                        {
                            services.AddTransient(serviceType, install);
                        }
                        else
                        {
                            services.AddTransient(install);
                        }
                    }
                };
            }
            return services;
        }
    }
}
